package com.xoms.front.service.impl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xoms.front.aspect.datasource.DataSourceSwitcher;
import com.xoms.front.controller.PutOrderProJsonBean;
import com.xoms.front.controller.res.bean.ROrderBean;
import com.xoms.front.controller.res.bean.ROrderListBean;
import com.xoms.front.model.AccountBean;
import com.xoms.front.model.OrderBean;
import com.xoms.front.model.ProOrderBean;
import com.xoms.front.model.ProStockBean;
import com.xoms.front.model.ProductBean;
import com.xoms.front.model.StoreHouseBean;
import com.xoms.front.model.TheatreBean;
import com.xoms.front.persist.dao.OrderDao;
import com.xoms.front.persist.dao.ProOrderDao;
import com.xoms.front.persist.dao.ProStockDao;
import com.xoms.front.persist.dao.ProductDao;
import com.xoms.front.persist.dao.StoreHouseDao;
import com.xoms.front.persist.dao.TheatreDao;
import com.xoms.front.service.OrderService;
import com.xoms.front.service.exception.ServiceException;
import com.xoms.front.service.res.PageResult;
import com.xoms.util.AppTextUtil;
import com.xoms.util.NumUtil;
import com.xoms.util.StringUtil;

@Service
public class OrderServiceImpl implements OrderService {

	@Autowired
	ProductDao productImpl;

	@Autowired
	OrderDao orderImpl;

	@Autowired
	ProOrderDao proOrderImpl;

	@Autowired
	StoreHouseDao storeHouseImpl;

	@Autowired
	ProStockDao proStockImpl;

	@Autowired
	TheatreDao theatreImpl;

	@Override
	public ROrderBean putProOrder(AccountBean account, List<PutOrderProJsonBean> pros, double actualMoeny, int payType,
			int isHand, String roomId, int isAuth, double authMoney, String authAccId, String vipCardId,
			String deviceMac) throws ServiceException {
		ROrderBean result = new ROrderBean();
		boolean flag = false;
		if (pros == null || pros.size() == 0) {
			throw new ServiceException("object_is_not_exist", "商品");
		}

		// 切换至影院数据源
		DataSourceSwitcher.setDataSourceType(DataSourceSwitcher.DATA_SOURCE_XOMS);
		// 当前账户所在的柜台
		StoreHouseBean storeHouse = storeHouseImpl.selectOneByAdminIdAndType(account.getAccid(), 2);
		if (storeHouse == null) {
			throw new ServiceException("object_is_not_exist", "当前账户关联柜台");
		}

		// 影院数据
		TheatreBean theatre = theatreImpl.selectOne();
		if (theatre == null) {
			throw new ServiceException("object_is_not_exist", "影院");
		}

		// 柜台id
		String sid = storeHouse.getSid();

		List<String> pids = new ArrayList<>();
		pros.forEach(pro -> {
			pids.add(pro.getPid());
		});

		Map<String, PutOrderProJsonBean> prosMap = pros.stream()
				.collect(Collectors.toMap(PutOrderProJsonBean::getPid, p -> p));

		// 根据pids查询
		List<ProductBean> lists = productImpl.selectListByPids(pids);
		if (lists == null || lists.size() == 0 || pids.size() != lists.size()) {
			throw new ServiceException("object_is_not_exist", "商品");
		}

		// 总价
		double money = 0;
		for (ProductBean pro : lists) {
			PutOrderProJsonBean orderPro = prosMap.get(pro.getPid());
			money += Math.abs(NumUtil.toDouble(pro.getPrice(), 0)) * Math.abs(NumUtil.toDouble(orderPro.getNum(), 0));
		}

		// 是否支付状态
		int isPay = 0;

		// 订单信息
		String oid = AppTextUtil.getPrimaryKey();
		OrderBean order = new OrderBean();
		order.setOid(oid);
		order.setTheatreCode(theatre.getTheatreCode());
		order.setActionId(account.getAccid());
		order.setStoreHouseId(sid);
		order.setOrderNo(AppTextUtil.getRandomNo());
		order.setOrderType(4);
		order.setSubject("商品-下单");
		order.setTargetId("");
		order.setCreateTime(new Timestamp(System.currentTimeMillis()));
		order.setStatus(isPay);
		order.setPayType(0);
		order.setDeviceMac(deviceMac);

		// 实际金额，优惠的价格
		double getMoney = money;
		// 是否授权优惠 0未授权，1授权
		if (isAuth == 1) {
			// 授权金额减少
			getMoney -= Math.abs(authMoney);
			order.setIsAuth(1);
			order.setAuthAccountId(authAccId);
			order.setAuthTime(new Timestamp(System.currentTimeMillis()));
			order.setAuthMoney(Math.abs(authMoney));
		} else {
			order.setIsAuth(0);
		}

		// 是否挂帐 0不挂，1挂
		if (isHand == 1) {
			if (StringUtil.isEmpty(roomId)) {
				throw new ServiceException("param_input_is_not_empty", "影厅");
			}
			order.setIsHand(1);
			order.setRoomId(roomId);
		} else {
			order.setIsHand(0);
			order.setRoomId("");
		}

		// 支付金额小于0
		if (getMoney < 0) {
			throw new ServiceException("pay_moeny_exc", "金额小于0");
		}

		order.setMoney(money);
		order.setGetMoney(getMoney);

		// 支付方式：1会员卡支付,2现金,3银联,4支付宝,5微信,6信用卡,7签单
		if (payType == 1) {

		} else if (payType == 2) {
			order.setPayType(2);
			order.setPayTime(new Timestamp(System.currentTimeMillis()));
			order.setCompleteTime(new Timestamp(System.currentTimeMillis()));
			order.setStatus(1);
			insertProOrder(account, sid, prosMap, lists, 1, order.getOid());// 插入商品订单
		} else if (payType == 4) {
			order.setPayType(4);
			order.setStatus(0);
			insertProOrder(account, sid, prosMap, lists, 0, order.getOid());// 插入商品订单
		} else if (payType == 5) {
			order.setPayType(5);
			order.setStatus(0);
			insertProOrder(account, sid, prosMap, lists, 0, order.getOid()); // 插入商品订单
		}

		flag = orderImpl.insert(order) > 0;
		if (!flag) {
			throw new ServiceException("database_insert_fail", "订单");
		}

		result.setOid(order.getOid());
		result.setIsHand(order.getIsHand());
		result.setRoomId(order.getRoomId());
		result.setOrderNo(order.getOrderNo());
		result.setPayType(order.getPayType());
		result.setStatus(order.getStatus());
		return result;
	}

	/**
	 * 新增产品订单
	 * 
	 * @param account
	 * @param sid
	 *            柜台id
	 * @param prosMap
	 * @param lists
	 *            商品列表
	 * @param isPay
	 *            是否支付 0为支付 1已支付
	 */
	private void insertProOrder(AccountBean account, String sid, Map<String, PutOrderProJsonBean> prosMap,
			List<ProductBean> lists, int isPay, String oid) {
		boolean flag;
		// 订单商品明细
		List<ProOrderBean> proOrderList = new ArrayList<>();
		List<ProStockBean> proStockList = new ArrayList<ProStockBean>();
		for (ProductBean pro : lists) {
			ProOrderBean proOrder = new ProOrderBean();
			proOrder.setOid(AppTextUtil.getPrimaryKey());
			proOrder.setProductId(pro.getPid());
			proOrder.setOrderId(oid);
			proOrder.setPrice(pro.getPrice());
			PutOrderProJsonBean orderPro = prosMap.get(pro.getPid());
			proOrder.setNumber(Math.abs(orderPro.getNum()));
			proOrder.setTotalPrice(Math.abs(orderPro.getNum()) * pro.getPrice());
			proOrder.setCreateTime(new Timestamp(System.currentTimeMillis()));
			proOrder.setStatus(isPay);
			proOrder.setAccountId(account.getAccid());
			proOrder.setCounterId(sid);
			proOrderList.add(proOrder);

			ProStockBean stock = new ProStockBean();
			stock.setStoreHouseId(sid);
			stock.setProductId(pro.getPid());
			stock.setStore(-Math.abs(orderPro.getNum()));
			proStockList.add(stock);
		}
		flag = proOrderImpl.insertBatch(proOrderList) > 0;
		if (!flag) {
			throw new ServiceException("database_insert_fail", "订单商品");
		}
		if (isPay == 1) { // 已经支付，// 更新库存
			flag = proStockImpl.updateBatch(proStockList) > 0;
			if (!flag) {
				throw new ServiceException("database_update_fail", "商品库存");
			}
		}
	}

	@Override
	public PageResult<ROrderListBean> orderList(AccountBean account, int page, int pageSize) {
		PageResult<ROrderListBean> result = new PageResult<>();
		// 切换至影院数据源
		DataSourceSwitcher.setDataSourceType(DataSourceSwitcher.DATA_SOURCE_XOMS);

		int count = orderImpl.selectCount();
		List<OrderBean> list = orderImpl.selectList(page, pageSize);

		List<ROrderListBean> resList = new ArrayList<>();
		if (list != null && list.size() > 0) {
			for (OrderBean o : list) {
				ROrderListBean rb = parseOrder(o);
				resList.add(rb);
			}
		}
		result.setCount(count);
		result.setData(resList);
		return result;
	}

	private ROrderListBean parseOrder(OrderBean o) {
		ROrderListBean resBean = new ROrderListBean();
		resBean.setOid(o.getOid());
		resBean.setIsHand(NumUtil.toInt(o.getIsHand(), 0));
		resBean.setRoomId(o.getRoomId());
		resBean.setOrderNo(o.getOrderNo());
		resBean.setOrderType(o.getOrderType());
		resBean.setTargetId(o.getTargetId());
		resBean.setMoney(o.getMoney());
		resBean.setGetMoney(o.getGetMoney());
		resBean.setIsAuth(NumUtil.toInt(o.getIsAuth(), 0));
		resBean.setAuthAccountId(o.getAuthAccountId());
		resBean.setAuthAccountName("");
		resBean.setAuthTime(o.getAuthTime() != null ? o.getAuthTime().getTime() / 1000 : 0);
		resBean.setAuthMoney(o.getAuthMoney());
		resBean.setCreateTime(o.getCreateTime() != null ? o.getCreateTime().getTime() / 1000 : 0);
		resBean.setStatus(NumUtil.toInt(o.getStatus(), 0));
		resBean.setPayType(NumUtil.toInt(o.getPayType(), 0));
		resBean.setPayTime(o.getPayTime() != null ? o.getPayTime().getTime() / 1000 : 0);
		resBean.setActionId(o.getActionId());
		resBean.setActionName("");
		resBean.setDeviceMac(o.getDeviceMac());
		resBean.setCompleteTime(o.getCompleteTime() != null ? o.getCompleteTime().getTime() / 1000 : 0);
		return resBean;
	}

}
